home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / xinetd / xinetd.2.0.6 / intcommon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-22  |  5.0 KB  |  235 lines

  1. /*
  2.  * (c) Copyright 1992 by Panagiotis Tsirigotis
  3.  * All rights reserved.  The file named COPYRIGHT specifies the terms 
  4.  * and conditions for redistribution.
  5.  */
  6.  
  7. static char RCSid[] = "$Id: intcommon.c,v 5.1 1992/11/01 00:01:21 panos Exp $" ;
  8.  
  9. #include <sys/types.h>
  10. #include <sys/time.h>
  11. #include <sys/socket.h>
  12. #include <signal.h>
  13. #include <syslog.h>
  14. #include <errno.h>
  15.  
  16. #include "int.h"
  17. #include "defs.h"
  18. #include "server.h"
  19. #include "config.h"
  20. #include "state.h"
  21.  
  22. void msg() ;
  23.  
  24.  
  25. void int_fail( ip, syscall )
  26.     struct intercept *ip ;
  27.     char *syscall ;
  28. {
  29.     msg( LOG_ERR, "fail", "%s failed: %m", syscall ) ;
  30.     (*ip->ops->exit)() ;
  31.     /* NOTREACHED */
  32. }
  33.  
  34.  
  35. /*
  36.  * Returns either a positive number or -1
  37.  */
  38. int int_select( max, read_mask )
  39.     int max ;
  40.     fd_set *read_mask ;
  41. {
  42.     char *func = "int_select" ;
  43.  
  44.     for ( ;; )
  45.     {
  46.         int n_ready ;
  47.  
  48.         n_ready = select( max+1, read_mask,
  49.                                             FD_SET_NULL, FD_SET_NULL, TIMEVAL_NULL ) ;
  50.         if ( n_ready > 0 )
  51.             return( n_ready ) ;
  52.         else if ( n_ready == -1 )
  53.             if ( errno == EINTR )
  54.                 continue ;
  55.             else
  56.             {
  57.                 msg( LOG_ERR, func, "select: %m" ) ;
  58.                 return( -1 ) ;
  59.             }
  60.     }
  61. }
  62.  
  63.  
  64. void int_exit( ip )
  65.     struct intercept *ip ;
  66. {
  67.     int status = INT_SERVER( ip )->exit_status ;
  68.     char *func = "int_exit" ;
  69.  
  70.     if ( debug.on )
  71.     {
  72.         if ( PROC_EXITED( status ) )
  73.             msg( LOG_DEBUG, func, "intercepted server died" ) ;
  74.         else if ( PROC_SIGNALED( status ) )
  75.             msg( LOG_DEBUG, func, "intercepted server received signal %d",
  76.                     PROC_TERMSIG( status ) ) ;
  77.     }
  78.     _exit( (int) PROC_EXITSTATUS( status ) ) ;
  79. }
  80.  
  81.  
  82. /*
  83.  * The ops vector must be installed before invoking this function
  84.  */
  85. void int_init( ip, serp )
  86.     struct intercept *ip ;
  87.     struct server *serp ;
  88. {
  89.     int flags ;
  90.     register unsigned u ;
  91.     char *func = "int_init" ;
  92.     void int_sighandler() ;
  93.  
  94.    /*
  95.     * Close all unneeded descriptors
  96.     */
  97.    for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
  98.    {
  99.       struct service *sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
  100.  
  101.       if ( sp == SERVER_SERVICE( serp ) )
  102.          continue ;
  103.       if ( LOG( CONF( sp ) )->log_type == L_FILE )
  104.          xlog_destroy( SDATA( sp )->log_handle ) ;
  105.       (void) close( SVC_FD( sp ) ) ;
  106.    }
  107.  
  108.     /*
  109.      * Setup signal handling
  110.      */
  111.     if ( (int) signal( SERVER_EXIT_SIG, int_sighandler ) == -1 )
  112.         int_fail( ip, "signal" ) ;
  113.     if ( (int) signal( INTERCEPT_SIG, int_sighandler ) == -1 )
  114.         int_fail( ip, "signal" ) ;
  115.     if ( (int) signal( SIGTERM, int_sighandler ) == -1 )
  116.         int_fail( ip, "signal" ) ;
  117.     
  118.     /*
  119.      * Initialize state
  120.      */
  121.     INTERCEPT( ip ) = TRUE ;
  122.     *INT_SERVER( ip ) = *serp ;
  123.     INT_REMOTE( ip ) = SERVER_FD( serp ) ;
  124.  
  125.     flags = FSM_RETURN_ERROR ;
  126. #ifdef DEBUG
  127.     flags |= FSM_ZERO_FREE ;
  128. #endif
  129.     INT_ALLOCATOR( ip ) = fsm_create( sizeof( channel_s ), 0, flags ) ;
  130.     if ( INT_ALLOCATOR( ip ) == NULL )
  131.     {
  132.         msg( LOG_ERR, func, ES_NOMEM ) ;
  133.         (*ip->ops->exit)() ;
  134.     }
  135.  
  136.     INT_CONNECTIONS( ip ) = pset_create( 0, 0 ) ;
  137.     if ( INT_CONNECTIONS( ip ) == NULL )
  138.     {
  139.         msg( LOG_ERR, func, ES_NOMEM ) ;
  140.         (*ip->ops->exit)() ;
  141.     }
  142. }
  143.  
  144.  
  145.  
  146. /*
  147.  * Make a new connection to the local server
  148.  */
  149. channel_s *int_newconn( ip, sinp, remote_socket )
  150.     struct intercept *ip ;
  151.     struct sockaddr_in *sinp ;
  152.     int remote_socket ;
  153. {
  154.     int socket_type = CONF( INT_SERVER( ip )->sp )->socket_type ;
  155.     struct sockaddr_in *local = INT_LOCALADDR( ip ) ;
  156.    channel_s *chp ;
  157.    int sd ;
  158.    char *func = "int_newconn" ;
  159.  
  160.    /*
  161.     * Get a socket and connect it to the local address
  162.     */
  163.    if ( ( sd = socket( AF_INET, socket_type, 0 ) ) == -1 )
  164.    {
  165.       msg( LOG_ERR, func, "socket creation: %m" ) ;
  166.       return( NULL ) ;
  167.    }
  168.  
  169.    if ( connect( sd, SA( local ), sizeof( *local ) ) == -1 )
  170.    {
  171.       msg( LOG_ERR, func, "connect: %m" ) ;
  172.       (void) close( sd ) ;
  173.       return( NULL ) ;
  174.    }
  175.  
  176.    chp = CHP( fsm_alloc( INT_ALLOCATOR( ip ) ) ) ;
  177.    if ( chp == NULL )
  178.    {
  179.       msg( LOG_ERR, func, ES_NOMEM ) ;
  180.       (void) close( sd ) ;
  181.       return( NULL ) ;
  182.    }
  183.  
  184.    if ( pset_add( INT_CONNECTIONS( ip ), chp ) == NULL )
  185.    {
  186.       msg( LOG_ERR, func, ES_NOMEM ) ;
  187.       fsm_free( INT_ALLOCATOR( ip ), (char *) chp ) ;
  188.       (void) close( sd ) ;
  189.       return( NULL ) ;
  190.    }
  191.  
  192.     chp->state = GOOD_CHANNEL ;
  193.     chp->from = *sinp ;
  194.    chp->local_socket = sd ;
  195.     chp->remote_socket = remote_socket ;
  196.    return( chp ) ;
  197. }
  198.  
  199.  
  200.  
  201. /*
  202.  * Check if the (address,port) in sinp is already in the connection table.
  203.  * Return value:
  204.  *    a connection pointer if the address is found
  205.  *    NULL if the address if not found
  206.  *
  207.  * *addr_checked is set to TRUE of FALSE depending on whether there
  208.  * is already a connection from the same IP address in the table.
  209.  */
  210. channel_s *int_lookupconn( ip, sinp, addr_checked )
  211.     struct intercept *ip ;
  212.    struct sockaddr_in *sinp ;
  213.    bool_int *addr_checked ;
  214. {
  215.    register unsigned u ;
  216.     register pset_h conntab = INT_CONNECTIONS( ip ) ;
  217.  
  218.    *addr_checked = FALSE ;
  219.  
  220.    for ( u = 0 ; u < pset_count( conntab ) ; u++ )
  221.    {
  222.       register channel_s *chp = CHP( pset_pointer( conntab, u ) ) ;
  223.  
  224.       if ( chp->from.sin_addr.s_addr == sinp->sin_addr.s_addr )
  225.       {
  226.          *addr_checked |= TRUE ;
  227.          if ( chp->from.sin_port == sinp->sin_port )
  228.             return( chp ) ;
  229.       }
  230.    }
  231.    return( NULL ) ;
  232. }
  233.  
  234.  
  235.